<!-- Author: Logan.Li -->
<template>
  <div class="redis-manager">
    <!-- 连接状态卡片 -->
    <el-card class="connection-card" shadow="hover">
      <template #header>
        <div class="card-header">
          <span>Redis连接状态</span>
          <el-button @click="testConnection" :loading="loading" type="primary" size="small">
            测试连接
          </el-button>
        </div>
      </template>
      
      <div class="connection-status">
        <el-tag :type="connected ? 'success' : 'danger'" size="large">
          {{ connected ? '已连接' : '未连接' }}
        </el-tag>
        <div class="redis-info" v-if="redisInfo && Object.keys(redisInfo).length > 0">
          <el-descriptions :column="3" border>
            <el-descriptions-item label="版本">{{ redisInfo.version || 'N/A' }}</el-descriptions-item>
            <el-descriptions-item label="运行模式">{{ redisInfo.mode || '单机' }}</el-descriptions-item>
            <el-descriptions-item label="连接数">{{ redisInfo.connections || 'N/A' }}</el-descriptions-item>
            <el-descriptions-item label="内存使用">{{ redisInfo.usedMemory || 'N/A' }}</el-descriptions-item>
            <el-descriptions-item label="总内存">{{ redisInfo.totalMemory || 'N/A' }}</el-descriptions-item>
            <el-descriptions-item label="运行时间">{{ redisInfo.uptime || 'N/A' }}</el-descriptions-item>
          </el-descriptions>
        </div>
      </div>
    </el-card>

    <!-- 缓存管理卡片 -->
    <el-card class="cache-card" shadow="hover" style="margin-top: 20px;">
      <template #header>
        <div class="card-header">
          <span>缓存管理</span>
          <div>
            <el-button @click="refreshKeys" :loading="loading" size="small">
              刷新键列表
            </el-button>
            <el-button @click="clearAllCache" type="danger" size="small" :loading="loading">
              清空所有缓存
            </el-button>
          </div>
        </div>
      </template>
      
      <div class="cache-operations">
        <!-- 搜索和过滤 -->
        <div class="search-section">
          <el-row :gutter="20">
            <el-col :span="12">
              <el-input
                v-model="searchPattern"
                placeholder="搜索键名 (支持通配符 *)"
                @keyup.enter="searchKeys"
                clearable>
                <template #append>
                  <el-button @click="searchKeys" :loading="loading">搜索</el-button>
                </template>
              </el-input>
            </el-col>
            <el-col :span="6">
              <el-select v-model="selectedKeyType" placeholder="键类型过滤" clearable>
                <el-option label="全部" value="all"></el-option>
                <el-option label="字符串" value="string"></el-option>
                <el-option label="哈希" value="hash"></el-option>
                <el-option label="列表" value="list"></el-option>
                <el-option label="集合" value="set"></el-option>
                <el-option label="有序集合" value="zset"></el-option>
              </el-select>
            </el-col>
            <el-col :span="6">
              <el-select v-model="selectedDb" placeholder="选择数据库">
                <el-option
                  v-for="db in dbOptions"
                  :key="db.value"
                  :label="db.label"
                  :value="db.value">
                </el-option>
              </el-select>
            </el-col>
          </el-row>
        </div>

        <!-- 缓存键列表 -->
        <div class="keys-section" style="margin-top: 20px;">
          <el-table 
            :data="filteredKeys" 
            v-loading="loading"
            height="300"
            @row-click="selectKey">
            <el-table-column prop="key" label="键名" min-width="200">
              <template #default="{ row }">
                <el-tag size="small" :type="getKeyTypeColor(row.type)">{{ row.type }}</el-tag>
                <span style="margin-left: 8px;">{{ row.key }}</span>
              </template>
            </el-table-column>
            <el-table-column prop="ttl" label="TTL" width="100">
              <template #default="{ row }">
                <span v-if="row.ttl === -1">永久</span>
                <span v-else-if="row.ttl === -2">已过期</span>
                <span v-else>{{ row.ttl }}s</span>
              </template>
            </el-table-column>
            <el-table-column prop="size" label="大小" width="100">
              <template #default="{ row }">
                {{ formatSize(row.size) }}
              </template>
            </el-table-column>
            <el-table-column label="操作" width="150">
              <template #default="{ row }">
                <el-button size="small" @click="viewKey(row.key)">查看</el-button>
                <el-button size="small" type="danger" @click="deleteKey(row.key)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>

        <!-- 键值操作区域 -->
        <div class="key-value-section" style="margin-top: 20px;">
          <el-row :gutter="20">
            <!-- 设置缓存 -->
            <el-col :span="12">
              <el-card>
                <template #header>设置缓存</template>
                <el-form :model="setForm" label-width="60px">
                  <el-form-item label="键名">
                    <el-input v-model="setForm.key" placeholder="请输入键名"></el-input>
                  </el-form-item>
                  <el-form-item label="值">
                    <el-input 
                      v-model="setForm.value" 
                      type="textarea" 
                      :rows="3"
                      placeholder="请输入值"></el-input>
                  </el-form-item>
                  <el-form-item label="过期时间">
                    <el-input-number 
                      v-model="setForm.expire" 
                      :min="0" 
                      placeholder="秒数，0为永久"
                      style="width: 100%"></el-input-number>
                  </el-form-item>
                  <el-form-item>
                    <el-button type="primary" @click="setCache" :loading="loading">设置</el-button>
                    <el-button @click="clearSetForm">清空</el-button>
                  </el-form-item>
                </el-form>
              </el-card>
            </el-col>

            <!-- 获取缓存 -->
            <el-col :span="12">
              <el-card>
                <template #header>获取缓存</template>
                <el-form :model="getForm" label-width="60px">
                  <el-form-item label="键名">
                    <el-input v-model="getForm.key" placeholder="请输入键名">
                      <template #append>
                        <el-button @click="getCache" :loading="loading">获取</el-button>
                      </template>
                    </el-input>
                  </el-form-item>
                  <el-form-item label="结果">
                    <el-input 
                      v-model="getForm.result" 
                      type="textarea" 
                      :rows="5"
                      readonly
                      placeholder="获取结果将显示在这里"></el-input>
                  </el-form-item>
                </el-form>
              </el-card>
            </el-col>
          </el-row>
        </div>

        <!-- 批量操作 -->
        <div class="batch-operations" style="margin-top: 20px;">
          <el-card>
            <template #header>批量操作</template>
            <el-row :gutter="20">
              <el-col :span="8">
                <el-button @click="exportKeys" :loading="loading" style="width: 100%">
                  导出所有键
                </el-button>
              </el-col>
              <el-col :span="8">
                <el-button @click="showImportDialog" style="width: 100%">
                  导入键值对
                </el-button>
              </el-col>
              <el-col :span="8">
                <el-button @click="flushDb" type="warning" :loading="loading" style="width: 100%">
                  清空当前数据库
                </el-button>
              </el-col>
            </el-row>
          </el-card>
        </div>
      </div>
    </el-card>

    <!-- 键值详情对话框 -->
    <el-dialog v-model="keyDetailVisible" :title="`键详情: ${selectedKeyName}`" width="60%">
      <div v-if="keyDetail">
        <el-descriptions :column="2" border>
          <el-descriptions-item label="键名">{{ keyDetail.key }}</el-descriptions-item>
          <el-descriptions-item label="类型">{{ keyDetail.type }}</el-descriptions-item>
          <el-descriptions-item label="TTL">
            <span v-if="keyDetail.ttl === -1">永久</span>
            <span v-else-if="keyDetail.ttl === -2">已过期</span>
            <span v-else>{{ keyDetail.ttl }}秒</span>
          </el-descriptions-item>
          <el-descriptions-item label="大小">{{ formatSize(keyDetail.size) }}</el-descriptions-item>
        </el-descriptions>
        
        <div style="margin-top: 20px;">
          <h4>值内容:</h4>
          <el-input 
            v-model="keyDetail.value" 
            type="textarea" 
            :rows="10"
            readonly></el-input>
        </div>
      </div>
      
      <template #footer>
        <el-button @click="keyDetailVisible = false">关闭</el-button>
        <el-button type="primary" @click="editKeyValue">编辑</el-button>
        <el-button type="danger" @click="deleteSelectedKey">删除</el-button>
      </template>
    </el-dialog>

    <!-- 导入对话框 -->
    <el-dialog v-model="importDialogVisible" title="导入键值对" width="50%">
      <el-input 
        v-model="importData" 
        type="textarea" 
        :rows="10"
        placeholder="请输入JSON格式的键值对数据"></el-input>
      
      <template #footer>
        <el-button @click="importDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="importKeys" :loading="loading">导入</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
// Author: Logan.Li
import { ref, onMounted, computed } from 'vue';
import { useRedisStore } from '@/stores/redis';
import { ElMessage, ElMessageBox } from 'element-plus';

const redisStore = useRedisStore();

// 响应式数据
const connected = ref(false);
const redisInfo = ref({});
const loading = ref(false);
const cacheKeys = ref([]);
const searchPattern = ref('*');
const selectedKeyType = ref('all');
const selectedDb = ref(0);

// 表单数据
const setForm = ref({
  key: '',
  value: '',
  expire: 0
});

const getForm = ref({
  key: '',
  result: ''
});

// 对话框状态
const keyDetailVisible = ref(false);
const importDialogVisible = ref(false);
const selectedKeyName = ref('');
const keyDetail = ref(null);
const importData = ref('');

// 数据库选项
const dbOptions = ref([
  { label: 'DB0 (默认)', value: 0 },
  { label: 'DB1', value: 1 },
  { label: 'DB2', value: 2 },
  { label: 'DB3', value: 3 },
  { label: 'DB4', value: 4 },
  { label: 'DB5', value: 5 }
]);

// 计算属性
const filteredKeys = computed(() => {
  if (!cacheKeys.value) return [];
  
  return cacheKeys.value.filter(key => {
    if (selectedKeyType.value !== 'all' && key.type !== selectedKeyType.value) {
      return false;
    }
    return true;
  });
});

// 方法
const testConnection = async () => {
  loading.value = true;
  try {
    const result = await redisStore.testConnection();
    connected.value = redisStore.connected;
    if (connected.value) {
      ElMessage.success('Redis连接成功');
      await fetchRedisInfo();
    } else {
      ElMessage.error('Redis连接失败');
    }
  } catch (error) {
    ElMessage.error('连接测试失败: ' + error.message);
  } finally {
    loading.value = false;
  }
};

const fetchRedisInfo = async () => {
  try {
    await redisStore.fetchRedisInfo();
    redisInfo.value = redisStore.redisInfo;
  } catch (error) {
    console.error('获取Redis信息失败:', error);
  }
};

const refreshKeys = async () => {
  loading.value = true;
  try {
    const keys = await redisStore.getCacheKeys(searchPattern.value);
    // 模拟键的详细信息
    cacheKeys.value = keys.map(key => ({
      key,
      type: 'string', // 实际应该从后端获取
      ttl: -1,
      size: Math.floor(Math.random() * 1000) + 100
    }));
    ElMessage.success(`获取到 ${keys.length} 个键`);
  } catch (error) {
    ElMessage.error('获取键列表失败: ' + error.message);
  } finally {
    loading.value = false;
  }
};

const searchKeys = async () => {
  await refreshKeys();
};

const setCache = async () => {
  if (!setForm.value.key || !setForm.value.value) {
    ElMessage.warning('请填写键名和值');
    return;
  }
  
  loading.value = true;
  try {
    await redisStore.setStringCache(setForm.value.key, setForm.value.value);
    ElMessage.success('设置成功');
    clearSetForm();
    await refreshKeys();
  } catch (error) {
    ElMessage.error('设置失败: ' + error.message);
  } finally {
    loading.value = false;
  }
};

const getCache = async () => {
  if (!getForm.value.key) {
    ElMessage.warning('请输入键名');
    return;
  }
  
  loading.value = true;
  try {
    const value = await redisStore.getStringCache(getForm.value.key);
    getForm.value.result = value || '键不存在或值为空';
    ElMessage.success('获取成功');
  } catch (error) {
    ElMessage.error('获取失败: ' + error.message);
    getForm.value.result = '获取失败: ' + error.message;
  } finally {
    loading.value = false;
  }
};

const selectKey = (row) => {
  setForm.value.key = row.key;
  getForm.value.key = row.key;
};

const viewKey = async (key) => {
  selectedKeyName.value = key;
  loading.value = true;
  try {
    const value = await redisStore.getStringCache(key);
    keyDetail.value = {
      key,
      type: 'string',
      ttl: -1,
      size: (value || '').length,
      value: value || ''
    };
    keyDetailVisible.value = true;
  } catch (error) {
    ElMessage.error('获取键详情失败: ' + error.message);
  } finally {
    loading.value = false;
  }
};

const deleteKey = async (key) => {
  try {
    await ElMessageBox.confirm(`确定要删除键 "${key}" 吗？`, '确认删除', {
      type: 'warning'
    });
    
    loading.value = true;
    // 这里需要实现删除功能
    ElMessage.success('删除成功');
    await refreshKeys();
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('删除失败: ' + error.message);
    }
  } finally {
    loading.value = false;
  }
};

const deleteSelectedKey = async () => {
  await deleteKey(selectedKeyName.value);
  keyDetailVisible.value = false;
};

const editKeyValue = () => {
  setForm.value.key = keyDetail.value.key;
  setForm.value.value = keyDetail.value.value;
  keyDetailVisible.value = false;
  ElMessage.info('已将键值填入设置表单，请修改后提交');
};

const clearSetForm = () => {
  setForm.value = {
    key: '',
    value: '',
    expire: 0
  };
};

const clearAllCache = async () => {
  try {
    await ElMessageBox.confirm('确定要清空所有缓存吗？此操作不可恢复！', '危险操作', {
      type: 'error'
    });
    
    loading.value = true;
    // 这里需要实现清空所有缓存的功能
    ElMessage.success('已清空所有缓存');
    await refreshKeys();
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('清空失败: ' + error.message);
    }
  } finally {
    loading.value = false;
  }
};

const exportKeys = async () => {
  try {
    const data = {};
    for (const keyInfo of cacheKeys.value) {
      const value = await redisStore.getStringCache(keyInfo.key);
      data[keyInfo.key] = value;
    }
    
    const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `redis-export-${new Date().toISOString().slice(0, 10)}.json`;
    a.click();
    URL.revokeObjectURL(url);
    
    ElMessage.success('导出成功');
  } catch (error) {
    ElMessage.error('导出失败: ' + error.message);
  }
};

const showImportDialog = () => {
  importDialogVisible.value = true;
};

const importKeys = async () => {
  try {
    const data = JSON.parse(importData.value);
    loading.value = true;
    
    let successCount = 0;
    for (const [key, value] of Object.entries(data)) {
      try {
        await redisStore.setStringCache(key, value);
        successCount++;
      } catch (error) {
        console.error(`导入键 ${key} 失败:`, error);
      }
    }
    
    ElMessage.success(`成功导入 ${successCount} 个键值对`);
    importDialogVisible.value = false;
    importData.value = '';
    await refreshKeys();
  } catch (error) {
    ElMessage.error('导入失败，请检查JSON格式: ' + error.message);
  } finally {
    loading.value = false;
  }
};

const flushDb = async () => {
  try {
    await ElMessageBox.confirm(`确定要清空数据库 DB${selectedDb.value} 吗？此操作不可恢复！`, '危险操作', {
      type: 'error'
    });
    
    loading.value = true;
    // 这里需要实现清空数据库的功能
    ElMessage.success(`已清空数据库 DB${selectedDb.value}`);
    await refreshKeys();
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('清空数据库失败: ' + error.message);
    }
  } finally {
    loading.value = false;
  }
};

// 工具方法
const getKeyTypeColor = (type) => {
  const colors = {
    string: 'primary',
    hash: 'success',
    list: 'warning',
    set: 'danger',
    zset: 'info'
  };
  return colors[type] || 'primary';
};

const formatSize = (size) => {
  if (size < 1024) return size + 'B';
  if (size < 1024 * 1024) return Math.round(size / 1024) + 'KB';
  return Math.round(size / (1024 * 1024)) + 'MB';
};

// 生命周期
onMounted(async () => {
  await testConnection();
  if (connected.value) {
    await refreshKeys();
  }
});
</script>

<style scoped>
.redis-manager {
  padding: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.connection-status {
  text-align: center;
  padding: 20px 0;
}

.redis-info {
  margin-top: 20px;
}

.search-section {
  margin-bottom: 20px;
}

.keys-section {
  margin: 20px 0;
}

.key-value-section {
  margin: 20px 0;
}

.batch-operations {
  margin-top: 20px;
}

.cache-operations {
  padding: 20px 0;
}
</style>
